package com.shu.rateLimiter;

import com.shu.timerTask.Base;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ssm
 * @version V1.0
 * @description: AtomicInteger 计数器限流
 * <p>
 * 弊端：如果我在单位时间1s内的前10ms，已经通过了100个请求，
 * 那后面的990ms，只能眼巴巴的把请求拒绝，我们把这种现象称为“突刺现象”
 * </p>
 * @date 2019/4/8 20:52
 */
public class AtomicRateLimiter extends Base {
    public CountDownLatch downLatch = new CountDownLatch(100);
    AtomicInteger success = new AtomicInteger(0); // 限流 <= 10个/s
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    AtomicInteger count = new AtomicInteger(0); // 限流 <= 10个/s

    public void access() {
        if (count.get() > 10) {
            System.out.println("用户过多,请稍后再试!");
        }
        count.incrementAndGet();
        System.out.println(success.incrementAndGet() + "处理中");
        try {
            //逻辑处理
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            count.decrementAndGet();
            downLatch.countDown();
        }
    }

    @Test
    public void concurrentAccess() throws InterruptedException {
        Runnable runnable = () -> {
            access();
        };
        stopWatch.start();
        for (int i = 0; i < 100; i++) {
            cachedThreadPool.submit(runnable);
        }
        downLatch.await();
        System.out.println("rateLimiter " + stopWatch.elapsed(TimeUnit.SECONDS));
    }
}
